home *** CD-ROM | disk | FTP | other *** search
-
- dir_no = 0
- dir_up = 1
- dir_down = 2
- dir_left = 3
- dir_right = 4
-
- -- -----------------------------------------------------------------
- function getDirShift(dir)
- local shiftX, shiftY = 0, 0
- if dir == dir_left then
- shiftX = -1
- elseif dir == dir_right then
- shiftX = 1
- elseif dir == dir_up then
- shiftY = -1
- elseif dir == dir_down then
- shiftY = 1
- end
- return shiftX, shiftY
- end
-
- -- -----------------------------------------------------------------
- local function isFreePlace(model, locX, locY)
- for x = locX, locX + model:getW() - 1 do
- for y = locY, locY + model:getH() - 1 do
- if not model_equals(-1, x, y) and not model_equals(model.index, x, y) then
- return false
- end
- end
- end
- return true
- end
-
- -- -----------------------------------------------------------------
- local function tryPlace(data, place)
- local locX = place.x
- local locY = place.y
-
- result = false
- if nil == data.closed[locX] then
- data.closed[locX] = {}
- end
- if not data.closed[locX][locY] then
- data.closed[locX][locY] = true
- if isFreePlace(data.model, locX, locY) then
- result = true
- end
- end
- return result
- end
-
- -- -----------------------------------------------------------------
- local function isInRect(x, y, w, h, destX, destY)
- return x <= destX and destX < x + w and y <= destY and destY < y + h
- end
- -- -----------------------------------------------------------------
- function findDir(model, destX, destY)
- -- Breadth-first search
- -- Find starting dir to the destination
- -- Return dir_no when there is no free path
- local locX, locY = model:getLoc()
- local w = model:getW()
- local h = model:getH()
-
- if isInRect(locX, locY, w, h, destX, destY) then
- return dir_no
- end
- if not model_equals(-1, destX, destY) then
- return dir_no
- end
-
- local data = {}
- data.closed = {}
- data.closed[locX] = {}
- data.closed[locX][locY] = true
- data.model = model
-
- local fifo = {}
- table.insert(fifo, {dir=dir_left, x=locX - 1, y=locY})
- table.insert(fifo, {dir=dir_right, x=locX + 1, y=locY})
- table.insert(fifo, {dir=dir_up, x=locX, y=locY - 1})
- table.insert(fifo, {dir=dir_down, x=locX, y=locY + 1})
-
- while table.getn(fifo) > 0 do
- local place = table.remove(fifo, 1)
- if tryPlace(data, place) then
- if isInRect(place.x, place.y, w, h, destX, destY) then
- return place.dir
- end
-
- table.insert(fifo, {dir=place.dir, x=place.x - 1, y=place.y})
- table.insert(fifo, {dir=place.dir, x=place.x + 1, y=place.y})
- table.insert(fifo, {dir=place.dir, x=place.x, y=place.y - 1})
- table.insert(fifo, {dir=place.dir, x=place.x, y=place.y + 1})
- end
- end
- return dir_no
- end
-
-